import site
import sys
from argparse import ArgumentParser
from os import system, path
from subprocess import getstatusoutput, getoutput

from loguru import logger


class Build:
	def __init__(self, file, name1, name2, model=None):
		"""

		:param file:
		:param model:
		"""
		# 构建可执行文件
		self.name2 = name2
		self.name1 = name1
		self.build = True
		# 使用缓存
		self.cache = False
		self.model = model
		self.file = file
		self.cmd = ""
		self.ver = ""
		self.name = ""
		self.images = ""
		self.container = ""
		self.images_id = ""
		self.info = {}
		self.bin = ""

	def init_info(self):
		"""
		初始化镜像信息
		:return:
		"""
		self.ver = getoutput("grep ver ./ver.sh | sed -n 1p").split("=")[-1]
		logger.info(f"当前版本: {self.ver}")

		self.name = self.name1
		self.info[1] = [self.name, self.ver]
		self.info[2] = [self.name, "latest"]

		self.name = self.name2
		self.info[3] = [self.name, self.ver]
		self.info[4] = [self.name, "latest"]
		self.bin = path.join("dist", str(self.file).replace(".py", ""))
		self.images = f"{self.name}:{self.ver}"

	def init_model(self):
		"""
		初始化
		:return:
		"""
		dist_packages_paths = site.getsitepackages()

		system("rm -rf ./*.spec ./dist")
		self.cmd = f"pyinstaller -F {self.file}  "
		if self.model is not None:
			self.cmd = self.cmd + f" -p {self.model} "

		for i in dist_packages_paths:
			self.cmd += f" -p {i}"
		print(self.cmd)

	def build_py(self):
		"""
		打包二进制执行文件
		:return:
		"""
		if self.build:
			if system(self.cmd) != 0:
				logger.error("构建失败!!!")
				sys.exit(2)
			logger.info("可执行文件构建成功,正在测试...")
			if system(f"./{self.bin} -h") != 0:
				logger.error("执行失败")
				sys.exit(3)
			system(f"cp -rf ./{self.bin} ./dist/pk")
			logger.info("可执行文件初步执行成功,开始生成镜像...")

	def build_images(self):
		"""
		开始构建镜像
		:return:
		"""
		c = f"docker build -t {self.images} .\n"
		if self.cache:
			c = f"docker build  --no-cache -t {self.images} .\n"
		print(c)
		if system(c) != 0:
			logger.error("镜像构建失败")
			sys.exit(4)
		logger.info("镜像构建成功,正在打标签...")

	def tag(self):
		"""
		开始打标签
		:return:
		"""
		c = "docker images | grep %s | grep %s | awk '{print $3}' | sed -n 1p" % (self.name, self.ver)
		info = getstatusoutput(c)
		if info[0] == 0:
			self.images_id = info[1]
			logger.info(f"当前镜像ID: {self.images_id}")
		else:
			logger.error("获取镜像ID失败")
			print(c)
			sys.exit(3)
		for i in self.info:
			name = self.info[i][0]
			ver = self.info[i][1]
			images = f"{name}:{ver}"
			c = f"docker tag {self.images_id} {images}"
			print(c)
			if system(c) == 0:
				logger.debug(f"正在推送: {images}")
				c = f"docker push {images}"
				print(c)
				if system(c) == 0:
					logger.info(f"推送成功: {images}")
				else:
					logger.error(f"推送失败: {images}")
			else:
				logger.error(f"标签设置失败: {images}")

	def delete(self):
		"""
		删除残留
		"""
		system("rm -rf *.spec ./dist")

	def start(self):
		self.init_info()
		self.init_model()
		self.build_py()
		self.build_images()
		self.tag()
		if deletes:
			self.delete()


if __name__ == "__main__":
	arg = ArgumentParser(description=f'自动打包', prog="流量消失工具-Linux")
	h = "需要打包的源码文件"
	arg.add_argument('-p', '--py', type=str, default="MultiTD.py", help=h, required=False)
	d = "ccr.ccs.tencentyun.com/liumou/ubuntu-kill"
	h = f"需要打包的镜像名称1,默认: {d}"
	arg.add_argument('-n1', '--name1', type=str, default=d, help=h, required=False)

	d = f"liuyi778/ubuntu-kill"
	h = f"需要打包的镜像名称2,默认: {d}"
	arg.add_argument('-n2', '--name2', type=str, default=d, help=h, required=False)

	#
	arg.add_argument('-delete', action='store_true', help='删除可执行文件')

	args = arg.parse_args()
	p = args.py
	n1 = args.name1
	n2 = args.name2
	deletes = args.delete
	b = Build(file=p, name1=n1, name2=n2)
	b.cache = False
	b.start()
